package com.tomecode.tools.maven.settings.gui.tabs;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.border.EmptyBorder;
import javax.swing.table.AbstractTableModel;

import com.tomecode.tools.maven.settings.model.Server;
import com.tomecode.tools.maven.settings.model.Settings;
import com.tomecode.util.gui.PanelFactory;
import com.tomecode.util.gui.component.Button;

/**
 * edit {@link Server}
 * 
 * @author Frastia Tomas
 * 
 */
public final class ServersTab extends JPanel {

	private static final long serialVersionUID = 8548966946773474729L;

	private final JTable serversTable;
	private final ServerTableModel serversTableModel;

	private final JPanel editorPanel;

	private final JTextField txtId;
	private final JTextField txtUserName;
	private final JTextField txtPassword;
	private final JTextField txtPassphrase;
	private final JTextField txtPrivateKey;
	private final JTextField txtFilePermissions;
	private final JTextField txtDirectoryPermissions;
	private final JTextField txtConfiguration;

	private final JLabel labError;

	private final Button bDelete;
	private final Button bEdit;
	private final Button bSave;

	public ServersTab(Settings settings) {
		super(new BorderLayout());
		setBorder(new EmptyBorder(10, 10, 0, 10));
		serversTableModel = new ServerTableModel(settings);
		serversTable = new JTable(serversTableModel);

		labError = new JLabel(" ");
		labError.setForeground(Color.red);

		serversTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		serversTable.setAutoscrolls(true);

		bDelete = new Button("Delete", false, new ActionListener() {
			public final void actionPerformed(ActionEvent e) {
				if (serversTable.getSelectedRow() == -1) {
					return;
				}
				serversTableModel.remove(serversTable.getSelectedRow());
				cleanTxts();
			}
		});
		bEdit = new Button("Edit", false, new ActionListener() {
			public final void actionPerformed(ActionEvent e) {
				if (serversTable.getSelectedRow() == -1) {
					return;
				}
				serversTableModel.update(serversTable.getSelectedRow(), txtId.getText(), txtConfiguration.getText(), txtDirectoryPermissions.getText(), txtFilePermissions.getText(), txtPassphrase.getText(), txtPassword.getText(), txtPrivateKey.getText(), txtUserName.getText());
				cleanTxts();
			}
		});
		bSave = new Button("Save", false, new ActionListener() {
			public final void actionPerformed(ActionEvent e) {
				serversTableModel.add(txtId.getText(), txtConfiguration.getText(), txtDirectoryPermissions.getText(), txtFilePermissions.getText(), txtPassphrase.getText(), txtPassword.getText(), txtPrivateKey.getText(), txtUserName.getText());
				cleanTxts();
			}
		});

		// JPanel pWrapTab = PanelFactory.createBorderLayou();
		// pWrapTab.add(new JScrollPane(serversTable), BorderLayout.CENTER);
		// pWrapTab.setPreferredSize(new Dimension(100, 100));
		// add(pWrapTab, BorderLayout.CENTER);
		add(new JScrollPane(serversTable), BorderLayout.CENTER);
		txtId = new JTextField();
		txtId.addKeyListener(new KeyAdapter() {
			public final void keyReleased(KeyEvent e) {
				checkIfServerIdExists();
			}
		});

		txtUserName = new JTextField();
		txtPassword = new JTextField();
		txtPassphrase = new JTextField();
		txtPrivateKey = new JTextField();
		txtFilePermissions = new JTextField();
		txtDirectoryPermissions = new JTextField();
		txtConfiguration = new JTextField();

		editorPanel = PanelFactory.createBorderLayout("Server");
		JPanel pFields = PanelFactory.createGridLayout(8, 1);
		editorPanel.add(pFields, BorderLayout.CENTER);
		pFields.add(PanelFactory.wrapWithLabelNorm("Id:", txtId, 127));
		pFields.add(PanelFactory.wrapWithLabelNorm("Username:", txtUserName, 78));
		pFields.add(PanelFactory.wrapWithLabelNorm("Password:", txtPassword, 79));
		pFields.add(PanelFactory.wrapWithLabelNorm("Passphrase:", txtPassphrase, 68));
		pFields.add(PanelFactory.wrapWithLabelNorm("Private Key:", txtPrivateKey, 73));
		pFields.add(PanelFactory.wrapWithLabelNorm("File Permissions:", txtFilePermissions, 43));
		pFields.add(PanelFactory.wrapWithLabelNorm("Directory Permissions:", txtDirectoryPermissions, 10));
		pFields.add(PanelFactory.wrapWithLabelNorm("Configuration:", txtConfiguration, 61));

		JPanel pSouth = PanelFactory.createBorderLayout(0, 0, 0, 0);
		pSouth.add(PanelFactory.createButtonsPanel(0, 0, 0, -4, bSave, bEdit, bDelete), BorderLayout.EAST);
		pSouth.add(labError, BorderLayout.CENTER);

		editorPanel.add(pSouth, BorderLayout.SOUTH);

		add(editorPanel, BorderLayout.SOUTH);

		serversTable.addKeyListener(new KeyAdapter() {
			public final void keyReleased(KeyEvent e) {
				selectInTable(serversTable.getSelectedRow());
			}

		});

		serversTable.addMouseListener(new MouseAdapter() {
			public final void mouseClicked(MouseEvent e) {
				selectInTable(serversTable.getSelectedRow());
			}
		});

	}

	protected final void checkIfServerIdExists() {
		if (txtId.getText().trim().length() == 0) {
			labError.setText("Server id cannot be empty");
			bSave.setEnabled(false);
			bEdit.setEnabled(false);
		} else if (serversTableModel.exists(txtId.getText())) {
			labError.setText("Server id already exists");
			bSave.setEnabled(false);
		} else {
			labError.setText(" ");
			bSave.setEnabled(true);
			bEdit.setEnabled(serversTable.getSelectedRow() != -1);
		}
	}

	private final void selectInTable(int selectedRow) {
		if (selectedRow == -1) {
			cleanTxts();
			return;
		}
		Server server = serversTableModel.get(selectedRow);
		txtId.setText(server.getId());
		txtConfiguration.setText(server.getConfiguration());
		txtDirectoryPermissions.setText(server.getDirectoryPermissions());
		txtFilePermissions.setText(server.getFilePermissions());
		txtPassphrase.setText(server.getPassphrase());
		txtPassword.setText(server.getPassword());
		txtPrivateKey.setText(server.getPrivateKey());
		txtUserName.setText(server.getUsername());

		bDelete.setEnabled(true);
		bEdit.setEnabled(true);
		bSave.setEnabled(true);
		checkIfServerIdExists();
	}

	private final void cleanTxts() {
		txtId.setText("");
		txtConfiguration.setText("");
		txtDirectoryPermissions.setText("");
		txtFilePermissions.setText("");
		txtPassphrase.setText("");
		txtPassword.setText("");
		txtPrivateKey.setText("");
		txtUserName.setText("");
		bDelete.setEnabled(false);
		bEdit.setEnabled(false);
		bSave.setEnabled(false);
		labError.setText(" ");
	}

	/**
	 * 
	 * @author Frastia Tomas
	 * 
	 */
	private final class ServerTableModel extends AbstractTableModel {

		private static final long serialVersionUID = 3479286243525778842L;

		private final String[] columns = new String[] { "Id", "Name", "Password" };

		private final Settings settings;

		private ServerTableModel(Settings settings) {
			this.settings = settings;
		}

		private final boolean exists(String id) {
			return settings.existsServer(id);
		}

		private final Server get(int selectedRow) {
			return settings.getServers().get(selectedRow);
		}

		private final void add(String id, String configuration, String directoryPermissions, String filePermissions, String passphrase, String password, String privateKey, String userName) {
			Server server = new Server();
			server.setId(id);
			server.setConfiguration(configuration);
			server.setDirectoryPermissions(directoryPermissions);
			server.setFilePermissions(filePermissions);
			server.setPassphrase(passphrase);
			server.setPassword(password);
			server.setPrivateKey(privateKey);
			server.setUsername(userName);
			settings.addServer(server);
			fireTableDataChanged();
			fireTableStructureChanged();
		}

		private final void update(int selectedRow, String id, String configuration, String directoryPermissions, String filePermissions, String passphrase, String password, String privateKey, String userName) {
			Server server = settings.getServers().get(selectedRow);
			server.setId(id);
			server.setConfiguration(configuration);
			server.setDirectoryPermissions(directoryPermissions);
			server.setFilePermissions(filePermissions);
			server.setPassphrase(passphrase);
			server.setPassword(password);
			server.setPrivateKey(privateKey);
			server.setUsername(userName);
			fireTableDataChanged();
		}

		public final void remove(int selectedRow) {
			settings.getServers().remove(selectedRow);
			fireTableDataChanged();
		}

		public final int getColumnCount() {
			return columns.length;
		}

		public final int getRowCount() {
			return this.settings.getServers().size();
		}

		public final String getColumnName(int column) {
			return columns[column];
		}

		public final Object getValueAt(int rowIndex, int columnIndex) {
			Server server = this.settings.getServers().get(rowIndex);
			if (columnIndex == 0) {
				return server.getId();
			} else if (columnIndex == 1) {
				return server.getUsername();
			} else if (columnIndex == 2) {
				return server.getPassword();
			}

			return null;
		}

	}
}
